#pragma once
#include <vector>
#include "LevelElement.h"
#include "PhysX.h"
#include "float3.h"
class InputMesh;
class NxActor;

/**
* Represents a mesh and its physics mesh
* @author Brecht Kets
*/
class PhysicsMesh: public LevelElement
{
public:
	/**
	* Enumeration representing Convex or Concave mesh
	*/
	enum Type { Convex, Concave };

	/**
	* Constructor
	* @param filename the obj file to load.
	* @param physicsFileName the physics file to load.
	* @param type convex or concave.
	*/
	PhysicsMesh(tstring filename, tstring physicsFileName,float3 loc, float3 rot,Type type, PhysX *pPhysX);

	/**
	* Destructor
	*/
	virtual ~PhysicsMesh(void);

	/*************************************************************************
	* implement this in derived class to initalize
	*/
	virtual void Initialize(ContentManager *pContentManager);
	/*************************************************************************
	* Implement this method in derived class 
	*/
	virtual void Tick(const InputState & refInputState);
	/*************************************************************************
	* Implement this method to Draw the D3DObject in the scene.
	* @param RenderContext to use.
	*/
	virtual void Draw(const RenderContext* pRenderContext);
	NxActor* GetActor();
protected:
	virtual void CreateEffect(ContentManager *pContentManager);

	/**
	* Build the vertex buffers.
	* Store them in a vector.
	*/
	virtual void BuildVertexBuffer();

	/**
	* Build the index buffers. 
	* Store them in a vector.
	*/
	virtual void BuildIndexBuffer();

	/**
	* Store the default technique and the shader variables
	*/
	virtual void GetEffectVariables(ID3D10Effect* effect);

	/**
	* Defines the input layout
	*/
	virtual void DefineInputlayout();

	/**
	* Retrieves the final world matrix 
	* Sets the Physics Global pos.
	*/
	virtual void SetPhysXGlobalPose();

	/**
	* Sets the Physics Global pos.
	* @World: een WorldMatrix
	*/
	virtual void SetPhysXGlobalPose(const D3DXMATRIX& World);

	/**
	* The cooked physics representation of this object
	*/
	NxActor *m_pActor;

private:
	/**
	* Creates a Convex mesh actor and adds it to the physics scene
	*/
	virtual bool BuildConvex(); 

	/**
	* Creates a Concave mesh actor and adds it to the physics scene
	*/
	virtual bool BuildConcave(); 

	Type m_Type;
	vector<InputMesh*>  m_Meshes;
	ID3D10EffectMatrixVariable* m_pWorldViewProjectionVariable;
	vector<ID3D10Buffer*> m_pVertexBuffers;
	vector<ID3D10Buffer*> m_pIndexBuffers;
	tstring m_filename, m_physicsFileName;

	ID3D10InputLayout*			m_pVertexLayout;
	ID3D10Effect*				m_pDefaultEffect;
	ID3D10EffectTechnique*		m_pDefaultTechnique;

	UINT m_VertexBufferStride;//stride value of vertex buffer

	PhysX *m_pPhysX;
	float3 m_Pos;
	float3 m_Rot;

	// -------------------------
	// Disabling default copy constructor and default assignment operator.
	// If you get a linker error from one of these functions, your class is internally trying to use them. This is
	// an error in your class, these declarations are deliberately made without implementation because they should never be used.
	// -------------------------
	PhysicsMesh(const PhysicsMesh& t);
	PhysicsMesh& operator=(const PhysicsMesh& t);
};

